// The strategy enum pattern
package org.effectivejava.examples.chapter06.item30;

/**
 * 比较复杂的枚举类（内部枚举类）：计算加班工资（策略模式） + 枚举方法体
 * 思路：
 * 1、工作日：超过8小时，算加班工资；休息日：全部算加班工资；加班工资系数由客户端传入；
 * 2、加班工资的计算方法封装到一个私有枚举类中（策略模式）；
 */
enum PayrollDay {
	MONDAY(PayType.WEEKDAY), //工作日
	TUESDAY(PayType.WEEKDAY), //工作日
	WEDNESDAY(PayType.WEEKDAY), //工作日
	THURSDAY(PayType.WEEKDAY), //工作日
	FRIDAY(PayType.WEEKDAY), //工作日
	SATURDAY(PayType.WEEKEND), //双休日
	SUNDAY(PayType.WEEKEND); //双休日

	//加班类型（内部枚举类）：工作日、休息日
	private final PayType payType;

	// 构造方法
	PayrollDay(PayType payType) {
		this.payType = payType;
	}

	// 支付报酬（供客户端调用）
	double pay(double hoursWorked, double payRate) {
		return payType.pay(hoursWorked, payRate);
	}

	// The strategy enum type（策略模式,计算加班工资）
	private enum PayType {
		// 工作日：超过8小时，算加班工资（除以2吗）
		WEEKDAY {
			double overtimePay(double hours, double payRate) {
				return hours <= HOURS_PER_SHIFT ? 0 : (hours - HOURS_PER_SHIFT)
						* payRate / 2;
			}
		},
		// 休息日：全部算加班工资（除以2吗）
		WEEKEND {
			double overtimePay(double hours, double payRate) {
				return hours * payRate / 2;
			}
		};

		private static final int HOURS_PER_SHIFT = 8; // 超过8小时算加班工资

		// 抽象方法（加班工资）
		abstract double overtimePay(double hrs, double payRate);

		// 计算加班工资
		double pay(double hoursWorked, double payRate) {
			double basePay = hoursWorked * payRate; // 基本工资
			return basePay + overtimePay(hoursWorked, payRate); // 基本工资+加班工资
		}
	}
}
